home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-20 | 17.4 KB | 712 lines | [TEXT/CWIE] |
- // =================================================================================
- //
- // CBaseControl.cpp ©1996 Microsoft Corporation All rights reserved.
- //
- // =================================================================================
-
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "ocheaders.h"
- #include "debug.h"
- #include "CBaseControl.h"
- #include "register.h"
- #include "ResourceMap.h"
- #include "dllentry.h"
-
-
- #define SafeReleaseAndNull(interface) \
- if (interface != NULL) { \
- interface->Release(); \
- interface = NULL; \
- }
-
- #define DEFAULT_CONTROL_SIZE 50
-
- #pragma mark === CBaseControl::Construction & Destruction ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::CBaseControl
- //=--------------------------------------------------------------------------=
- // Constructor
- //
- CBaseControl::CBaseControl(void)
- {
- mUnkOuterP = NULL;
- mContainerSiteP = NULL;
- mContainerP = NULL;
- mActive = false;
- mCPContainerP = NULL;
- mContextInfo = NULL;
- mActiveContext = NULL;
- mSize.h = mSize.v = DEFAULT_CONTROL_SIZE;
- *mID = 0;
-
- mContextInfo = new LArray(sizeof(CBaseContextInfo*));
- DLLAddRef();
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::~CBaseControl
- //=--------------------------------------------------------------------------=
- // Destructor
- //
- CBaseControl::~CBaseControl(void)
- {
- if (mContextInfo)
- {
- ArrayIndexT i = LArray::index_First;
- CBaseContextInfo* ContextInfoP;
- while (mContextInfo->FetchItemAt(i++, &ContextInfoP))
- delete ContextInfoP;
- delete mContextInfo;
- mContextInfo = NULL;
- }
-
- StopIdling();
- SafeReleaseAndNull(mContainerP);
- SafeReleaseAndNull(mContainerSiteP);
- SafeReleaseAndNull(mUnkOuterP);
- SafeReleaseAndNull(mCPContainerP);
- DLLRelease();
- }
-
-
- #pragma mark === CBaseControl::IUnknown ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IUnknown::QueryInterface
- //=--------------------------------------------------------------------------=
- // Returns a pointer to the specified interface on a component to which a
- // client currently holds an interface pointer.
- //
- STDMETHODIMP
- CBaseControl::QueryInterface(REFIID inRefID, void** outObj)
- {
- ErrorCode Result = CBaseCOM::QueryInterface(inRefID, outObj);
-
- if ( Result == E_NOINTERFACE )
- {
- void* pv = nil;
-
- if ( inRefID == IID_IObjectWithSite )
- pv = (void*)(IObjectWithSite* ) this;
- else if (inRefID == IID_IControl )
- pv = (void*)(IControl*) this;
- else if (inRefID == IID_IPersist || inRefID == IID_IPersistPropertyBag)
- pv = (void*)(IPersistPropertyBag*) this;
-
- else if (inRefID == IID_IConnectionPointContainer)
- {
- if ( mCPContainerP )
- return mCPContainerP->QueryInterface(IID_IConnectionPointContainer, outObj);
- }
-
- *outObj = pv;
-
- // if we got an interface, ref it and return ok
- if ( pv )
- {
- ((IUnknown*) pv)->AddRef();
- Result = S_OK;
- }
- }
-
- return Result;
- }
-
-
-
- #pragma mark === CBaseControl::IObjectWithSite ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IObjectWithSite::SetSite
- //=--------------------------------------------------------------------------=
- // informs the control of it's client site display
- // location within it's container
- //
- STDMETHODIMP
- CBaseControl::SetSite(IUnknown* inClientSite)
- {
- // remove any idlers that have been set up
- StopIdling();
-
- // Release the outer unknown
- SafeReleaseAndNull(mUnkOuterP);
-
- // Set our outer unknown to the one provided
- mUnkOuterP = (IUnknown*) inClientSite;
-
- // if we got a site, get the other interfaces we need.
- if (mUnkOuterP != NULL)
- {
- // Only release these if we get called with a non-null inClientSite
- // Should only ever get called with a null client site if the object
- // is going away. Then these interfaces get released in the destructor.
- SafeReleaseAndNull(mContainerSiteP);
- SafeReleaseAndNull(mContainerP);
-
- // Add our reference to the unknown
- mUnkOuterP->AddRef();
-
- // Get the IContainerSite interface
- mUnkOuterP->QueryInterface(IID_IContainerSite, &mContainerSiteP);
-
- // if we got that, get the IContainer interface
- if ( mContainerSiteP )
- {
- mContainerSiteP->GetContainer(&mContainerP);
- if ( mContainerP )
- mContainerP->AddRef();
-
- StartIdling();
- }
- }
-
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IObjectWithSite::GetSite
- //=--------------------------------------------------------------------------=
- // obtains a pointer to the controls client site.
- //
- STDMETHODIMP
- CBaseControl::GetSite(REFIID inRefID, void** outSite)
- {
- if ( inRefID == IID_IUnknown )
- *outSite = (void*) mUnkOuterP;
- else if ( inRefID == IID_IContainerSite )
- *outSite = (void*) mContainerSiteP;
-
- return S_OK;
- }
-
-
- #pragma mark === CBaseControl::IControl ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::Draw
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::Draw(DrawContext* inContext)
- {
- if (inContext->DrawAspect != DVASPECT_CONTENT)
- return DV_E_DVASPECT;
-
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::OnContextChange
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::OnContextChange(UInt32 inContextID, ContextCommand inCommand)
- {
- ErrorCode Result = S_OK;
-
- CBaseContextInfo* ContextInfo = GetContextInfoByID(inContextID);
-
- switch ( inCommand )
- {
- case AddContext:
- if (!ContextInfo)
- {
- if ((ContextInfo = NewContext(inContextID)) != NULL)
- mContextInfo->InsertItemsAt(1, 1, &ContextInfo);
- else
- {
- #if BE_STRICT
- DebugStr("\pAddContext couldn't get a context info object.");
- #endif // BE_STRICT
- Result = E_FAIL;
- }
- }
- else
- {
- #if BE_STRICT
- DebugStr("\pAddContext with duplicate ContextID.");
- #endif // BE_STRICT
- Result = E_FAIL;
- }
- break;
-
- case RemoveContext:
- if (ContextInfo)
- {
- if (ContextInfo == mActiveContext)
- mActiveContext = NULL;
-
- mContextInfo->RemoveItemsAt(1, mContextInfo->FetchIndexOf(&ContextInfo));
- delete ContextInfo;
- }
- else
- {
- Result = E_FAIL;
- #if BE_STRICT
- DebugStr("\pRemoveContext on a context the control doesn't have.");
- #endif // BE_STRICT
- }
-
- break;
-
- case UpdateContext:
- if (ContextInfo)
- ContextInfo->Update(false);
- else
- {
- Result = E_FAIL;
- #if BE_STRICT
- DebugStr("\pUpdateContext on a context the control doesn't have.");
- #endif // BE_STRICT
- }
- break;
-
- case ActivateContext:
- if (ContextInfo)
- {
- if (mActiveContext != NULL)
- {
- CBaseContextInfo* ActiveContextInfo = GetContextInfoByID(inContextID);
- if (ActiveContextInfo)
- ActiveContextInfo->Deactivate(false);
- else
- {
- Result = E_UNEXPECTED;
- #if BE_STRICT
- DebugStr("\pCan't deactivate a context left active.");
- #endif // BE_STRICT
- }
- #if BE_STRICT
- DebugStr("\pActivateContext before a DeactivateContext.");
- #endif // BE_STRICT
- }
- Result = ContextInfo->Activate(false);
- mActiveContext = ContextInfo;
- }
- else
- {
- Result = E_FAIL;
- #if BE_STRICT
- DebugStr("\pActivateContext on a context the control doesn't have.");
- #endif // BE_STRICT
- }
- break;
-
- case DeactivateContext:
- if (ContextInfo)
- {
- if (mActiveContext == ContextInfo)
- Result = ContextInfo->Deactivate(false);
- else
- {
- Result = E_UNEXPECTED;
- #if BE_STRICT
- DebugStr("\pDeactivateContext on an inactive context.");
- #endif // BE_STRICT
- }
- mActiveContext = NULL;
- }
- else
- {
- Result = E_FAIL;
- #if BE_STRICT
- DebugStr("\pDeactivateContext on a context the control doesn't have.");
- #endif // BE_STRICT
- }
- break;
-
- default:
- Result = E_FAIL;
- break;
- }
-
- return Result;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::GetID
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::GetID(Int32 inBufferSize, Char8* outID)
- {
- Int32 IDLen;
- Char8* Source;
-
- // if we have an id then us it
- if (*mID)
- {
- IDLen = *mID;
- Source = (Char8*)(mID + 1);
- }
- // otherwise use the hard coded registry name
- else
- {
- Source = kOCXFullUserTypeName;
- IDLen = strlen(Source);
- }
-
- if (--inBufferSize < IDLen)
- IDLen = inBufferSize;
-
- ::BlockMove(Source, outID, IDLen);
- *(outID + IDLen) = '\0';
-
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::GetUsedArea
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::GetUsedArea(PlatformRegion* outUsedArea)
- {
- #pragma unused (outUsedArea)
- return E_FAIL;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl:IControl:SetFocus
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::SetFocus(FocusCommand inCommand, FocusSet inFocus)
- {
- #pragma unused (inCommand, inFocus)
- return E_FAIL;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::DoMouse
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
- {
- #pragma unused (inMouseET, inEvent)
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::DoKey
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::DoKey(KeyEventType inKeyET, Char8 inChar, PlatformEvent* inEvent)
- {
- #pragma unused (inKeyET, inChar, inEvent)
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl:IControl:DoActivate
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::DoActivate(ActivateEventType inActiveET, UInt32 inContextID, PlatformEvent* inEvent)
- {
- #pragma unused (inContextID, inEvent)
- switch (inActiveET)
- {
- case AppActivate:
- case WindowActivate:
- mActive = true;
- break;
-
- case AppDeactivate:
- case WindowDeactivate:
- mActive = false;
- break;
- }
-
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::DoSystemEvent
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::DoSystemEvent(PlatformEvent* inEvent)
- {
- #pragma unused (inEvent)
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IControl::DoIdle
- //=--------------------------------------------------------------------------=
- STDMETHODIMP
- CBaseControl::DoIdle(Uint32 IdleRefCon)
- {
- #pragma unused (IdleRefCon)
- return S_OK;
- }
-
-
- #pragma mark === CBaseControl::IPersist ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IPersist::GetClassID
- //=--------------------------------------------------------------------------=
- //
- STDMETHODIMP
- CBaseControl::GetClassID(CLSID* ClassID)
- {
- #pragma unused (ClassID)
- return E_NOTIMPL;
- }
-
-
- #pragma mark === CBaseControl::IPersistPropertyBag ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IPersistPropertyBag::InitNew
- //=--------------------------------------------------------------------------=
- //
- STDMETHODIMP
- CBaseControl::InitNew(void)
- {
- // BUGBUG: Maybe do stuff here?
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IPersistPropertyBag::Load
- //=--------------------------------------------------------------------------=
- //
- STDMETHODIMP
- CBaseControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
- {
- Int32 i;
- VARIANT v;
-
- v.vt = VT_BSTR;
- v.bstrVal = NULL;
-
- // get the starting size
- if (PropertyBag->Read("width", &v, ErrorLog) == S_OK && v.bstrVal)
- {
- ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
- mSize.h = i;
- CoTaskMemFree(v.bstrVal);
- }
-
- if (PropertyBag->Read("height", &v, ErrorLog) == S_OK && v.bstrVal)
- {
- ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
- mSize.v = i;
- CoTaskMemFree(v.bstrVal);
- }
-
- if (PropertyBag->Read("id", &v, ErrorLog) == S_OK && v.bstrVal)
- {
- Int16 IDLen = *((Uint32*) v.bstrVal);
-
- if (IDLen > 255)
- IDLen = 255;
- ::BlockMove(v.bstrVal + sizeof(Uint32), mID + 1, IDLen);
- *mID = IDLen;
- CoTaskMemFree(v.bstrVal);
- }
-
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::IPersistPropertyBag::Save
- //=--------------------------------------------------------------------------=
- //
- STDMETHODIMP
- CBaseControl::Save(IPropertyBag* PropertyBag, BOOL ClearDirty, BOOL SaveAllProperties)
- {
- #pragma unused (PropertyBag, ClearDirty, SaveAllProperties)
- return E_NOTIMPL;
- }
-
-
- #pragma mark === CBaseControl::Protected Methods ===
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::InvalAllContexts
- //=--------------------------------------------------------------------------=
- //
- void
- CBaseControl::InvalAllContexts()
- {
- Int16 Index = 1;
- DrawContext Context = {BeginPortType};
- UInt32 ContextID;
-
- while (GetContextID(Index++, &ContextID))
- {
- if ( mContainerSiteP->AcquireContext(ContextID, &Context) == S_OK)
- {
- if (Context.PortType == QDWindowPortType)
- ::InvalRect(&Context.Location);
- mContainerSiteP->ReleaseContext(&Context);
- }
- }
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::StartIdling [virtual]
- //=--------------------------------------------------------------------------=
- //
- Boolean8
- CBaseControl::StartIdling(void)
- {
- return false;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::StartIdling [virtual]
- //=--------------------------------------------------------------------------=
- //
- Boolean8
- CBaseControl::StopIdling(void)
- {
- if (mContainerSiteP)
- return mContainerSiteP->SetIdleTime(RemoveAllIdlers, NULL) == S_OK;
- else
- return false;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::NewContext [virtual]
- //=--------------------------------------------------------------------------=
- //
- CBaseContextInfo*
- CBaseControl::NewContext(Uint32 inContextID)
- {
- return new CBaseContextInfo(this, inContextID);
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::GetContextID
- //=--------------------------------------------------------------------------=
- //
- Boolean8
- CBaseControl::GetContextID(Int16 inIndex, Uint32* outContextID)
- {
- Boolean8 Result;
- CBaseContextInfo* ContextInfo = GetContextInfoByIndex(inIndex);
-
- if ((Result = ContextInfo != NULL) != false)
- *outContextID = ContextInfo->GetContextID();
-
- return Result;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::GetContextInfoByID
- //=--------------------------------------------------------------------------=
- //
- CBaseContextInfo*
- CBaseControl::GetContextInfoByID(Uint32 inContextID)
- {
- ArrayIndexT Index = LArray::index_First;
- CBaseContextInfo* ContextInfo;
-
- while (mContextInfo->FetchItemAt(Index++, &ContextInfo))
- if (ContextInfo && ContextInfo->GetContextID() == inContextID)
- return ContextInfo;
-
- return NULL;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseControl::GetContextInfoByIndex
- //=--------------------------------------------------------------------------=
- //
- CBaseContextInfo*
- CBaseControl::GetContextInfoByIndex(Int16 inIndex)
- {
- CBaseContextInfo* ContextInfo;
-
- if (!mContextInfo->FetchItemAt(inIndex, &ContextInfo))
- ContextInfo = NULL;
-
- return ContextInfo;
- }
-
-
- #pragma mark === CBaseContextInfo Construction & Destruction ===
-
- //=--------------------------------------------------------------------------=
- // CBaseContextInfo::CBaseContextInfo
- //=--------------------------------------------------------------------------=
- // Constructor
- //
- CBaseContextInfo::CBaseContextInfo(CBaseControl* inControlP, Uint32 ContextID)
- {
- mContextID = ContextID;
- mControlP = inControlP;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseContextInfo::~CBaseContextInfo
- //=--------------------------------------------------------------------------=
- // Destructor
- //
- CBaseContextInfo::~CBaseContextInfo(void)
- {
- }
-
-
- #pragma mark === CBaseContextInfo Stub Implementation ===
-
- //=--------------------------------------------------------------------------=
- // CBaseContextInfo::Update
- //=--------------------------------------------------------------------------=
- // Update
- //
- ErrorCode
- CBaseContextInfo::Update(Boolean8 Acquired)
- {
- #pragma unused (Acquired)
- return S_OK;
- }
-
- //=--------------------------------------------------------------------------=
- // CBaseContextInfo::Activate
- //=--------------------------------------------------------------------------=
- // Activate
- //
- ErrorCode
- CBaseContextInfo::Activate(Boolean8 Acquired)
- {
- #pragma unused (Acquired)
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CBaseContextInfo::Deactivate
- //=--------------------------------------------------------------------------=
- // Deactivate
- //
- ErrorCode
- CBaseContextInfo::Deactivate(Boolean8 Acquired)
- {
- #pragma unused (Acquired)
- return S_OK;
- }
-